from django.db import models
from django.contrib.auth.models import User

""" Possible future concepts for inclusion:
Organizational Goals
Roles
Organizational Units
"""

class Task(models.Model):
    """ Tasks are the primary unit of work generally associated with completion of some objective.
    They have cost (in hours) - real or estimated depending on if the task has been
    completed. Cost is used to provide details on objectives, including cost forecasting
    and relative measure of completion """
    label = models.CharField(maxlength=100)
    description = models.TextField()
    createdby = models.ForeignKey(User, related_name="tasks_created")
    created_date = models.DateField()
    last_modified = models.DateField(blank=True, null=True)
    cost = models.IntegerField(blank=True, null=True)
    complete = models.BooleanField()
    objective = models.ForeignKey('Task', null=True, blank=True, related_name="objectives") # objective < task
    tags = models.ManyToManyField('Tag', null=True, blank=True, related_name="tasks")

    def __str__(self):
        return '%s' % (self.label,)

    class Admin:
        pass


class Tag(models.Model):
    """ Our nod at web2.0 (I know I know - I hate myself now). Interface will be key.
    Ajax type ui with matching of existing tag labels, tag clouds, and tag based RSS
    are all possibilities. Require tags on objects not created in relation to something
    else (e.g. a task is not in the context of a specific objective can be created
    but should then have at least one tag to provide interface mechanism for
    these 'unattached' objects.
    """
    label = models.CharField(maxlength=100)
    createdby = models.ForeignKey(User, related_name='tags')
    created_date = models.DateField()

    def __str__(self):
        return '%s' % (self.label,)

    class Admin:
        pass


class Milestone(models.Model):
    """ Important dates in the lifecycle of a project. Not intended to be assigned,
    more important for the generation of notifications, awareness of related timelines,
    and 'big picture' overview.
    """
    project = models.ForeignKey('Project', related_name="milestones")
    label = models.CharField(maxlength=100)
    date = models.DateField()
    description = models.TextField()
    createdby = models.ForeignKey(User, related_name='events_created')
    contact = models.ManyToManyField(User, blank=True, null=True, related_name='milestones')
    created_date = models.DateField()
    last_modified = models.DateField(null=True, blank=True)

    def __str__(self):
        return '%s' % (self.project.label + " :: " + self.label,)

    class Admin:
        pass


class Objective(models.Model):
    """ Objectives are an assigned unit of work. It should be in the service of a project.
    They have states, tasks, notifications, related task info (e.g. estimated cost, %complete).
    Interface might include some immediate feedback on assignments of objectives (warning
    when certain threshold is met) to help prevent over-extension. """
    # Standard metadata
    label = models.CharField(maxlength=100)
    description = models.TextField()
    createdby = models.ForeignKey(User, related_name="objectives_created")
    created_date = models.DateField()
    last_modified = models.DateField(blank=True, null=True)
    obj_states =  (
      ('unscheduled', 'Unscheduled'),
      ('assigned','Assigned'),
      ('complete','Complete'),)
    state  = models.CharField(maxlength=100, choices=obj_states, default="unscheduled")
    lead = models.ForeignKey(User, null=True, blank=True, related_name="objectives") # objective > user
    project = models.ForeignKey('Project', null=True, related_name="objectives") # objective > project
    target_date = models.DateField(blank=True, null=True)

    def __str__(self):
        return '%s' % (self.label,)

    class Admin:
        pass


class Project(models.Model):
    """ A project is a collection of objectives in the fulfillment of College-wide goals.
    Projects should have some sort of justification based on value provided to the students or
    community. They should also have some entry point from request to project status, though
    not necessarily in this system. They have clients, owners, objectives, milestones. """
    label = models.CharField(maxlength=100)
    description = models.TextField()
    college_goal = models.ForeignKey('Goal', null=True, blank=True)
    created_by = models.ForeignKey(User, related_name='projects_created')
    created_date = models.DateField()
    last_modified = models.DateField(null=True, blank=True)
    clients = models.ManyToManyField(User, null=True, blank=True, related_name="projects_owned")
    tags = models.ManyToManyField(Tag, null=True, blank=True, related_name="projects")

    def __str__(self):
        return '%s' % (self.label,)

    class Admin:
        pass


class Goal(models.Model):
    """ Organization-wide goals that inform the selection of projects to be undertaken.
    """
    label = models.CharField(maxlength=100)
    description = models.TextField()
    created_by = models.ForeignKey(User, related_name='goals_created')
    created_date = models.DateField()

    def __str__(self):
        return '%s' % (self.label,)

    class Admin:
        pass




